﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;

namespace AspNetMvc.Demo1.Validations
{
     [AttributeUsage(AttributeTargets.Field |
         AttributeTargets.Property, AllowMultiple = false,
             Inherited = true)]
    public class IsbnValidationAttribute 
         : System.ComponentModel.DataAnnotations.ValidationAttribute
    {
          /**
         * This class is courtesy:
         * http://www.java2s.com/Open-Source/CSharp/
         * Inversion-of-Control-Dependency-Injection/Spring.net/
         * Spring/Validation/Validators/ISBNValidator.cs.htm
         * 
         * This class is used for demonstration purposes
         * of performing an ISBN validation.  Should you
         * wish to use this in your project, please
         * consult the license agreement here:
         * http://www.apache.org/licenses/LICENSE-2.0
         **/
        private static readonly String SEP = "(?:\\-|\\s)";
        private static readonly String GROUP = "(\\d{1,5})";
        private static readonly String PUBLISHER = "(\\d{1,7})";
        private static readonly String TITLE = "(\\d{1,6})";
        static readonly String ISBN10_PATTERN = 
           "^(?:(\\d{9}[0-9X])|(?:" + GROUP + SEP + PUBLISHER + 
                SEP + TITLE + SEP + "([0-9X])))$";
        static readonly String ISBN13_PATTERN = 
           "^(978|979)(?:(\\d{10})|(?:" + SEP + GROUP + SEP + 
               PUBLISHER + SEP + TITLE + SEP + "([0-9])))$";
        public IsbnValidationAttribute() : 
            base("Invalid ISBN number") 
        {
        }
        public override bool IsValid(object value)
        {
            // Convert to string and fix up the ISBN
            string isbn = value.ToString();
            string code = (isbn == null)
                              ? null
                              : isbn.Trim().Replace("-", "").Replace(" ", "");
            // check the length
            if ((code == null) || (code.Length < 10
                                   || code.Length > 13))
            {
                return false;
            }
            // validate/reformat using regular expression
            Match match;
            String pattern;
            if (code.Length == 10)
            {
                pattern = ISBN10_PATTERN;
            }
            else
            {
                pattern = ISBN13_PATTERN;
            }
            match = Regex.Match(code, pattern);
            return match.Success && match.Index == 0 &&
                   match.Length == code.Length;
        }
    }
}